package com.voice.server.utils;


import com.voice.core.api.utils.HttpCommonUtil;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.HmacAlgorithms;
import org.apache.commons.codec.digest.HmacUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.Map;
import java.util.TreeMap;

public class SignUtil {

    public static String getFirstHeaderValue(HttpServletRequest request,String name){
        Enumeration<String> enumeration= request.getHeaders(name);
        if(!enumeration.hasMoreElements()) return null;
        return enumeration.nextElement();
    }

    public static String sign(HttpServletRequest request, String secret) {
        String signString = buildStringToSign(request);
        return Base64.encodeBase64String(new HmacUtils(HmacAlgorithms.HMAC_SHA_256, secret).hmac(signString));
    }

    public static String buildStringToSign(HttpServletRequest request) {
        StringBuilder sb = new StringBuilder();
        sb.append(request.getMethod().toUpperCase()).append("\n");
        if(getFirstHeaderValue(request,"accept")!=null){
            sb.append(getFirstHeaderValue(request,"accept"));
        }
        sb.append("\n");

        if(getFirstHeaderValue(request,"content-md5")!=null){
            sb.append(getFirstHeaderValue(request,"content-md5"));
        }
        sb.append("\n");

        if(getFirstHeaderValue(request,"content-type")!=null){
            sb.append(getFirstHeaderValue(request,"content-type"));
        }
        sb.append("\n");

        if(getFirstHeaderValue(request,"date")!=null){
            sb.append(getFirstHeaderValue(request,"date"));
        }
        sb.append("\n");

        sb.append(buildHeaders(request));
        sb.append(buildResource(request));
        return sb.toString();
    }

    private static String buildResource(HttpServletRequest request) {
        StringBuilder result = new StringBuilder();
        result.append(request.getRequestURI());

        TreeMap<String, String> parameter = new TreeMap();
        if (null != request.getQueryString()) {
            String[] params=request.getQueryString().split("&");
            for(String param:params){
                String[] keyValue=param.split("=");
                if(!parameter.containsKey(keyValue[0])){
                    if(keyValue.length==1) parameter.put(keyValue[0],null);
                    if(keyValue.length==1) parameter.put(keyValue[0],keyValue[1]);
                }
            }
        }
        request.getParameterMap().forEach((key,value)->parameter.put(key,value[0]));
        if (parameter.size() > 0) {
            result.append("?");
            result.append(HttpCommonUtil.buildSignParamString(parameter));
        }
        return result.toString();
    }

    private static String buildHeaders(HttpServletRequest request) {
        Map<String, String> headersToSign = new TreeMap();
        for(String header:getFirstHeaderValue(request,"x-ca-signature-headers").split(",")){
            headersToSign.put(header,getFirstHeaderValue(request,header));
        }
        StringBuilder sb = new StringBuilder();
        HttpCommonUtil.mapConsume(headersToSign,(isFirst,entry)->sb.append(entry.getKey()).append(":").append(entry.getValue()).append("\n"));
        return sb.toString();
    }


}
